#include "N1Delegate.h"
#include "N1Unit.h"

#ifdef N1LIB_SELFTEST

class Listener 
{
public:
    int  call;
    Listener() : call(0) { };
    long delegate() { call++; return call; };
    int  delegate2(double d) { call += (int)d; return call; };
    void del3() { call++; }
    void del4(int x) { call+=x; }
};

class Notifier
{
    N1DelegatePtr<long> *m_p1;
    N1DelegatePtr<int, double> *m_p2;
    N1DelegatePtr<void> *m_p3;
    N1DelegatePtr<void, int> *m_p4;

public:
    ~Notifier() 
    {
         delete m_p1;
         delete m_p2;
         delete m_p3;
         delete m_p4;
    }
    void setDelegate1(N1DelegatePtr<long> *p1) { m_p1 = p1; };
    void setDelegate2(N1DelegatePtr<int, double> *p2) { m_p2 = p2; };
    void setDelegate3(N1DelegatePtr<void> *p3) { m_p3 = p3; };
    void setDelegate4(N1DelegatePtr<void, int> *p4) { m_p4 = p4; };

    int callDelegates()
    {
        m_p1->invoke();
        int ret = m_p2->invoke(3.14);
        m_p3->invoke();
        m_p4->invoke(5);
        return ret;
    }
};

N1TEST(N1DelegateTest1)
{
    Listener l;
    Notifier n;

    n.setDelegate1( new N1Delegate<Listener, long>(&l, &Listener::delegate) );
    n.setDelegate2( new N1Delegate<Listener, int, double>(&l,&Listener::delegate2) );
    n.setDelegate3( new N1Delegate<Listener>(&l,&Listener::del3) );
    n.setDelegate4( new N1Delegate<Listener, void, int>(&l,&Listener::del4) );

    n.callDelegates();

    N1CHECK(l.call==10, "Error!!!");
}

#endif //N1LIB_SELFTEST
